package com.epam.concurrency.threadpool;

import java.util.LinkedList;
import java.util.List;

/**
 * My implementation of a simple Thread Pool
 * @author Iurii Miedviediev
 * @version 1.0 Build 05.08.2014
 */
public class MyThreadPool {
    private final int numThreads;
    private final Worker[] threads;
    private final List<Runnable> tasks;

    public MyThreadPool(int numWorkers) {
        this.numThreads = numWorkers;
        tasks = new LinkedList();
        threads = new Worker[numWorkers];

        for (int i = 0; i < numWorkers; i++) {
            threads[i] = new Worker();
        }
    }

    /**
     * Start all threads in the pool
     */
    public void startPool() {
        for(Worker worker : threads) {
            worker.start();
        }
    }

    /**
     * Add new task to the Thread Pool
     * @param task Runnable to execute
     */
    public void execute(Runnable task) {
        synchronized(tasks) {
            tasks.add(task);
            tasks.notify();
        }
    }

    /**
     * Standard thread pool worker
     */
    private class Worker extends Thread {
        public void run() {
            Runnable task;

            while (true) {
                synchronized(tasks) {
                    while (tasks.isEmpty()) {
                        try {
                            tasks.wait();
                        } catch (InterruptedException mayBeIgnored){
                            //Here exception may be ignored
                        }
                    }
                    task = tasks.remove(0);
                    task.run();
                }
            }
        }
    }
}
